import sys
import traceback
from redis import Redis
import json
from app.schemas.risk_schema import FeeRiskSchema
from sqlalchemy.orm import Session
from app.common.enums import algo_types
from app.common.enums.resp_enum import ErrTypes
from app.common import exceptions
from app import utils
from app import conf
#from app import utils
from app.services.channel import get_channel_fees
from app.common.exceptions import GenericException

import logging
logger = logging.getLogger(__name__)


IP_WHITE_LIST_KEY = 'ip_white_list'
CARD_DATA_KEY = 'card_data'

DAY_EX_SECONDS = 60 * 60 * 24 * 2   # 2天
MONTH_EX_SECONDS = 60 * 60 * 24 * 60 # 2个月\
LIMIT_TRANS_AMOUNT = int(conf.LIMIT_TRANS_AMOUNT)
LIMIT_DAY_AMOUNT = int(conf.LIMIT_DAY_AMOUNT)
LIMIT_MONTH_AMOUNT = int(conf.LIMIT_MONTH_AMOUNT)

##################### 交易限额 ####################
    

#def is_in_single_trans_limit(db: Session, r: Redis, limit_amount, call_params: dict={}):
def is_in_single_trans_limit(limit_amount, call_params: dict={}):
    logger.info('>> 校验单卡单笔交易限额')
    amount = call_params.get('amount')
    limit_amount = utils.amt.scale_up_100x(limit_amount)
    if not amount:
        raise GenericException(ErrTypes.risk_lack_of_params)
    elif amount > limit_amount:
        raise GenericException(ErrTypes.rule_card_over_single_limit)
    else:
        logger.info('规则校验通过')
        return True

def is_in_day_limit(r: Redis, limit_amount, call_params: dict={}):
    logger.info('>> 校验单卡日交易限额')
    trans_date = utils.get_time_now(type=5)
    amount = call_params.get('amount')
    card_no = call_params.get('card_no')
    logger.info(f'卡[{card_no}]日交易数据校验')
    if not amount or not card_no:
        raise GenericException(ErrTypes.risk_lack_of_params)
    key = f'{CARD_DATA_KEY}:day:{card_no}:{trans_date}'
    card_data = {}
    data_js = r.get(key)
    if data_js:
        card_data = json.loads(data_js)
        new_amount = card_data.get('amount') + amount
        limit_amount = utils.amt.scale_up_100x(limit_amount)
        if new_amount > limit_amount:
            logger.error(f'单卡日交易超出限额')
            raise GenericException(ErrTypes.rule_card_over_day_limit)
        else:
            logger.info('规则校验通过')
            return True
    else:
        logger.info('规则检验通过，未查到日交易数据')
        return True
    

def is_in_month_limit(r: Redis, limit_amount, call_params: dict={}):
    logger.info('>> 校验单卡月交易限额')
    trans_month = utils.get_time_now(type=6)
    amount = call_params.get('amount')
    card_no = call_params.get('card_no')
    if not amount or not card_no:
        raise GenericException(ErrTypes.risk_lack_of_params)
    key = f'{CARD_DATA_KEY}:month:{card_no}:{trans_month}'
    card_data = {}
    data_js = r.get(key)
    if data_js:
        card_data = json.loads(data_js)
        new_amount = card_data.get('amount') + amount
        limit_amount = utils.amt.scale_up_100x(limit_amount)
        if new_amount > limit_amount:
            logger.error(f'单卡月交易超出限额')
            raise GenericException(ErrTypes.rule_card_over_month_limit)
        else:
            logger.info('规则校验通过')
            return True
    else:
        logger.info('规则检验通过，未查到月交易数据')
        return True

def is_ip_in_white_list(r: Redis, ip_addr: str, target_sys: str='open_api') -> bool:
    try:
        v = r.get(f'{IP_WHITE_LIST_KEY}:{ip_addr}:{target_sys}')
        if v:
            return True
        else:
            return False
    except Exception as err:
        raise GenericException(ErrTypes.risk_ip_not_allowed)


